package com.my.lucky.service;

import com.my.lucky.config.IwencaiConfig;
import com.my.lucky.dto.GaiNianDTO;
import com.my.lucky.dto.SummaryBean;
import com.my.lucky.entity.GaiNianInfo;
import com.my.lucky.entity.StockLimitDown;
import com.my.lucky.entity.StockLimitUp;
import com.my.lucky.entity.SysInfo;
import com.my.lucky.model.Gainian60Boll;
import com.my.lucky.model.Stock;
import com.my.lucky.model.Stock60Boll;
import com.my.lucky.repository.*;
import com.my.lucky.service.impl.StockServiceImpl;
import com.my.lucky.util.BollingerBandCalculator;
import com.my.lucky.util.DateUtils;
import com.my.lucky.util.PinyinUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class GaiNianInfoService {

    @Autowired
    private GainianInfoRepository repository;

    @Autowired
    private StockRepository stockRepository;

    @Autowired
    private Gainian60BollRepository gainian60BollRepository;

    @Autowired
    private StockLimitUpService stockLimitUpService;

    @Autowired
    private StockLimitDownRepository downRepository;


    @Autowired
    private StockServiceImpl stockService;

    @Autowired
    private IwencaiConfig iwencaiConfig;


    @Autowired
    private IWencaiServiceTools wencaiServiceTools;


    public static void main(String[] args) {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime startTime = DateUtils.minusDaysExcludeWeekendAndYesterday(now, 2);
        System.out.println(startTime);
        LocalDateTime startTime1 = DateUtils.minusDaysExcludeWeekendAndYesterday(now, 3);
        System.out.println(startTime1);

        // 示例1: 将带时间的日期转换为仅日期格式
//        String originalDateTime = "2025-09-05 15:31:07.516635";
//        String result1 = timeFormat(originalDateTime, "yyyy-MM-dd HH:mm:ss.SSSSSS", "yyyy-MM-dd");
//        log.info("示例1转换结果: " + result1);  // 输出: 2025-09-05
//
//        // 示例2: 其他格式转换
//        String dateStr2 = "05/09/2025 3:31 PM";
//        String result2 = timeFormat(dateStr2, "dd/MM/yyyy h:mm a", "yyyy年MM月dd日");
//        log.info("示例2转换结果: " + result2);  // 输出: 2025年09月05日
//
//        // 示例3: 仅日期格式转换
//        String dateStr3 = "20250905";
//        String result3 = timeFormat(dateStr3, "yyyyMMdd", "MM-dd-yyyy");
//        log.info("示例3转换结果: " + result3);  // 输出: 09-05-2025

//
//        LocalDate result = getDateBeforeExcludingWeekends(3);
//        log.info("今天前 "  + " 个工作日的日期是：" + result);
    }

    /**
     * 将LocalDateTime格式化为指定格式的字符串
     *
     * @param dateTime  待格式化的LocalDateTime对象（不可为null）
     * @param formatter 格式化器（不可为null）
     * @return 格式化后的字符串
     * @throws IllegalArgumentException 若参数为null
     */
    public static String timeFormat(LocalDateTime dateTime, DateTimeFormatter formatter) {
        if (dateTime == null) {
            throw new IllegalArgumentException("LocalDateTime对象不能为null");
        }
        if (formatter == null) {
            throw new IllegalArgumentException("DateTimeFormatter不能为null");
        }
        return dateTime.format(formatter);
    }

    /**
     * 概念数据
     * @param now
     * @return
     */
    public GaiNianDTO getSealOrderAmountSummary(LocalDateTime now) {
        GaiNianDTO gaiNianDTO = new GaiNianDTO();
        if (now == null) {
            now = LocalDateTime.now();
        }
//        List<Map<String, Object>> result = new ArrayList<>();
        List<SummaryBean> result = new ArrayList<>();

        log.info("getSealOrderAmountSummary=====1");
        LocalDate today = now.toLocalDate();//today.minusDays(1);
//        List<Stock> allStock = stockRepository.findByCreatedAtBetweenOrderByRankPositionAsc(LocalDateTime.of(today, LocalTime.MIDNIGHT), LocalDateTime.of(today, LocalTime.MAX));
        List<Stock> allStock = stockRepository.findByTradeDateBetweenOrderByCodeAscTradeDateAsc(today, today);
        Map<String, Integer> sunstocks = new HashMap<>();
        Map<String, Integer> sunstocksUP = new HashMap<>();//上涨的家数
        Integer stocksUP = 0;//上涨的家数
        Integer stocksDown = 0;//下跌的家数
        Integer stocksLimit = 0;//涨停的家数
        Integer stockspin = 0;//平的家数
//       log.info("allStock==111=="+allStock.size());

        BigDecimal todayAll = new BigDecimal(0.0); //总资金
        BigDecimal todayAllMain = new BigDecimal(0.0); //总主力资金
        for (Stock stock : allStock) {
//            log.info("stock=="+stock);
            todayAll = todayAll.add(stock.getCapitalFlow() != null ? stock.getCapitalFlow() : new BigDecimal(0.0));
            todayAllMain = todayAllMain.add(stock.getMainCapitalFlow() != null ? stock.getMainCapitalFlow() : new BigDecimal(0.0));
            if (stock.getChangePercent() != null && stock.getChangePercent() > 0) {
                stocksUP = stocksUP + 1;
            } else if (stock.getChangePercent() != null && stock.getChangePercent() < 0) {
                stocksDown = stocksDown + 1;
            } else {
                stockspin = stockspin + 1;
            }
            String concept = stock.getConcept();
            if (concept != null && !concept.isEmpty()) {// 按分号分割概念字符串
                String[] parts = concept.split(";");
                for (String part : parts) {
                    if (!part.trim().isEmpty()) {
                        sunstocks.put(part, sunstocks.get(part) == null ? 1 : sunstocks.get(part) + 1);
                        if (stock.getChangePercent() != null && stock.getChangePercent() > 0) {
                            sunstocksUP.put(part, sunstocksUP.get(part) == null ? 1 : sunstocksUP.get(part) + 1);
                        }
                    }
                }
            }
        }
        iwencaiConfig.setSunstocks(sunstocks);
        log.info("getSealOrderAmountSummary=====2");
        Map<String, Integer> sunstockslimit = new HashMap<>();//涨停数量
        List<StockLimitUp> stocks = stockLimitUpService.getTodayLimitUpStocksBy(LocalDateTime.of(today, LocalTime.MIDNIGHT), LocalDateTime.of(today, LocalTime.MAX));
        List<StockLimitDown> downstocks = downRepository.findTodayLimitUpStocksAndRecordTimeBetween(LocalDateTime.of(today, LocalTime.MIDNIGHT), LocalDateTime.of(today, LocalTime.MAX));
//        System.out.println(downstocks);
        gaiNianDTO.setStocksDownLimit(downstocks!=null?downstocks.size():0);
//        List<StockLimitUp> stocks = downRepository..getTodayLimitUpStocksBy(LocalDateTime.of(today, LocalTime.MIDNIGHT), LocalDateTime.of(today, LocalTime.MAX));
        for (StockLimitUp stock : stocks) {
            String concept = stock.getGainians();
            String limitUpReason = stock.getLimitUpReason();
            if (concept != null && !concept.isEmpty()) {// 按分号分割概念字符串
                // 优化后的代码
                String[] parts = {};
                String[] partsr = {};

                // 处理第一个字符串的分割，避免空指针和空字符串
                if (concept != null && !concept.isEmpty()) {
                    parts = concept.split(";");
                }

                // 处理第二个字符串的分割，注意split需要转义，同时避免空指针和空字符串
                if (limitUpReason != null && !limitUpReason.isEmpty()) {
                    partsr = limitUpReason.split("\\+"); // 这里需要用\\+转义，否则会报错
                }

                // 合并两个数组并去重
                Set<String> resultSet = new HashSet<>();
                // 添加第一个数组的元素
                resultSet.addAll(Arrays.asList(parts));
                // 添加第二个数组的元素（Set会自动去重）
                resultSet.addAll(Arrays.asList(partsr));

                // 转换为数组（如果需要）
                String[] finalResult = resultSet.toArray(new String[0]);
                for (String part : finalResult) {
                    if (!part.trim().isEmpty()) {
                        sunstockslimit.put(part, sunstockslimit.get(part) == null ? 1 : sunstockslimit.get(part) + 1);
                    }
                }
            }
            stocksLimit = stocks.size();
        }

        gaiNianDTO.setStocksLimit(stocksLimit);
        gaiNianDTO.setStocksUP(stocksUP);
        gaiNianDTO.setStocksDown(stocksDown);
        gaiNianDTO.setStocksPin(stockspin);
        gaiNianDTO.setAllstocks(allStock.size());

        List<GaiNianInfo> allEntities = repository.findByCreateTimeBetween(LocalDateTime.of(today, LocalTime.MIDNIGHT), LocalDateTime.of(today, LocalTime.MAX));//repository.findByCreateTime(LocalDateTime.of(today, LocalTime.MIDNIGHT));
        log.info("getSealOrderAmountSummary==" + allEntities.size());
        if (allEntities == null || allEntities.size() <= 0) {
            return gaiNianDTO;
        }
        log.info("getSealOrderAmountSummary==222");
        Map<String, BigDecimal> map20 = calculateSummaryForDays(now, 19);
        Map<String, BigDecimal> map10 = calculateSummaryForDays(now, 9);
        Map<String, BigDecimal> map7 = calculateSummaryForDays(now, 6);
        Map<String, BigDecimal> map6 = calculateSummaryForDays(now, 5);
        Map<String, BigDecimal> map5 = calculateSummaryForDays(now, 4);
        Map<String, BigDecimal> map4 = calculateSummaryForDays(now, 3);
        Map<String, BigDecimal> map3 = calculateSummaryForDays(now, 2);
        Map<String, BigDecimal> map2 = calculateSummaryForDays(now, 1);
        Map<String, BigDecimal> map1 = calculateSummaryForDays(now, 0);
        // 获取所有不同的概念代码

        // 为每个概念代码计算各时间段的汇总
//        log.info(allEntities.size());

        LocalDateTime day2S = DateUtils.minusDaysExcludeWeekendAndYesterday(LocalDateTime.of(today, LocalTime.MIDNIGHT), 1);
        LocalDateTime day2e = LocalDateTime.of(day2S.toLocalDate(), LocalTime.MAX);
        List<GaiNianInfo> day2allEntities = repository.findByCreateTimeBetween(day2S, day2e);
        Map<String, GaiNianInfo> day2all = new HashMap<>();
        for (GaiNianInfo gaiNianInfo : day2allEntities) {
            String gainianCode = gaiNianInfo.getGainianCode();
            day2all.put(gainianCode, gaiNianInfo);
        }

        LocalDateTime day3S = DateUtils.minusDaysExcludeWeekendAndYesterday(LocalDateTime.of(today, LocalTime.MIDNIGHT), 2);
        LocalDateTime day3e = LocalDateTime.of(day3S.toLocalDate(), LocalTime.MAX);
        List<GaiNianInfo> day3allEntities = repository.findByCreateTimeBetween(day3S, day3e);
        Map<String, GaiNianInfo> day3all = new HashMap<>();
        for (GaiNianInfo gaiNianInfo : day3allEntities) {
            String gainianCode = gaiNianInfo.getGainianCode();
            day3all.put(gainianCode, gaiNianInfo);
        }

//        LocalDateTime day4S = minusDaysExcludeWeekendAndYesterday(LocalDateTime.of(today, LocalTime.MIDNIGHT), 3);
//        LocalDateTime day4e = LocalDateTime.of(day4S.toLocalDate(), LocalTime.MAX);
//        List<GaiNianInfo> day4allEntities = repository.findByCreateTimeBetween(day4S, day4e);
//        Map<String, GaiNianInfo> day4all = new HashMap<>();
//        for (GaiNianInfo gaiNianInfo : day4allEntities) {
//            String gainianCode = gaiNianInfo.getGainianCode();
//            day4all.put(gainianCode, gaiNianInfo);
//        }

        LocalDateTime day5S = DateUtils.minusDaysExcludeWeekendAndYesterday(LocalDateTime.of(today, LocalTime.MIDNIGHT), 4);
        LocalDateTime day5e = LocalDateTime.of(day5S.toLocalDate(), LocalTime.MAX);
        List<GaiNianInfo> day5allEntities = repository.findByCreateTimeBetween(day5S, day5e);
        Map<String, GaiNianInfo> day5all = new HashMap<>();
        for (GaiNianInfo gaiNianInfo : day5allEntities) {
            String gainianCode = gaiNianInfo.getGainianCode();
            day5all.put(gainianCode, gaiNianInfo);
        }

        LocalDateTime day6S = DateUtils.minusDaysExcludeWeekendAndYesterday(LocalDateTime.of(today, LocalTime.MIDNIGHT), 5);
        LocalDateTime day6e = LocalDateTime.of(day6S.toLocalDate(), LocalTime.MAX);
        List<GaiNianInfo> day6allEntities = repository.findByCreateTimeBetween(day6S, day6e);
        Map<String, GaiNianInfo> day6all = new HashMap<>();
        for (GaiNianInfo gaiNianInfo : day6allEntities) {
            String gainianCode = gaiNianInfo.getGainianCode();
            day6all.put(gainianCode, gaiNianInfo);
        }

        LocalDateTime day7S = DateUtils.minusDaysExcludeWeekendAndYesterday(LocalDateTime.of(today, LocalTime.MIDNIGHT), 6);
        LocalDateTime day7e = LocalDateTime.of(day7S.toLocalDate(), LocalTime.MAX);
        List<GaiNianInfo> day7allEntities = repository.findByCreateTimeBetween(day7S, day7e);
        Map<String, GaiNianInfo> day7all = new HashMap<>();
        for (GaiNianInfo gaiNianInfo : day7allEntities) {
            String gainianCode = gaiNianInfo.getGainianCode();
            day7all.put(gainianCode, gaiNianInfo);
        }

        for (GaiNianInfo entity : allEntities) {
//            Map<String, Object> summary = new LinkedHashMap<>();
//            String code = entity.getGainianCode();
//
            gaiNianDTO.setCreatedAt(entity.getCreateTime());
//            summary.put("gainianCode", code);
//
//            summary.put("rankPosition", entity.getRankPosition());
//            summary.put("oldRankPosition", entity.getOldRankPosition());
//
//            summary.put("marketValue", entity.getMarketValue());
//            summary.put("changePercent", entity.getChangePercent());
//            summary.put("gainianName", entity.getGainianName());
//            summary.put("gainianNamepy", PinyinUtils.getWordInitials(entity.getGainianName()));
//
//            // 计算各时间段的汇总
//            summary.put("day2now", day2all.get(code) != null ? day2all.get(code).getSealOrderAmount() : 0);
//            summary.put("day3now", day3all.get(code) != null ? day3all.get(code).getSealOrderAmount() : 0);
////            summary.put("day4now", day4all.get(code) != null ? day4all.get(code).getSealOrderAmount() : 0);
//            summary.put("day5now", day5all.get(code) != null ? day5all.get(code).getSealOrderAmount() : 0);
//            summary.put("day6now", day6all.get(code) != null ? day6all.get(code).getSealOrderAmount() : 0);
//            summary.put("day7now", day7all.get(code) != null ? day7all.get(code).getSealOrderAmount() : 0);
//
//            summary.put("day20", map20.get(code));
//            summary.put("day10", map10.get(code));
//            summary.put("day7", map7.get(code));
//            summary.put("day6", map6.get(code));
//            summary.put("day5", map5.get(code));
//            summary.put("day4", map4.get(code));
//            summary.put("day3", map3.get(code));
//            summary.put("day2", map2.get(code));
//            summary.put("day1", map1.get(code));
//            Integer suns = sunstocks.get(entity.getGainianName());
//            if ((suns == null || suns == 0) && (allStock!=null && allStock.size()>0)) {
//                suns=0;
//                continue;
////                suns=0;
//            }
//            summary.put("sunstocks", suns);
//
//            Integer sunsup = sunstocksUP.get(entity.getGainianName());
//            if (sunsup == null || sunsup == 0) {
//                sunsup = 0;
//            }
//
//            summary.put("sunstocksup", sunsup);
//
//            Double sunstocksupratio = suns == 0 ? 0.00 : new Double(sunsup.intValue()) / new Double(suns.intValue());
////            log.info("sunstocksupratio=="+sunstocksupratio);
//            summary.put("sunstocksupratio", sunstocksupratio * 100);
//
//            Integer sunslimit = sunstockslimit.get(entity.getGainianName());
//            if (sunslimit == null || sunslimit == 0) {
//                sunslimit = 0;
//            }
//            summary.put("sunstockslimit", sunslimit);
//            summary.put("sunstockslimitratio", (suns == 0 ? 0.00 : new Double(sunslimit.intValue()) / new Double(suns.intValue())) * 100);

            // 创建SummaryBean实例替代Map
            SummaryBean summary = new SummaryBean();
            String code = entity.getGainianCode();

            // 设置创建时间（原gaiNianDTO的属性也转移到bean中）
            summary.setCreatedAt(entity.getCreateTime());
            summary.setGainianCode(code);

            summary.setRankPosition(entity.getRankPosition());
            summary.setOldRankPosition(entity.getOldRankPosition());

            summary.setMarketValue(entity.getMarketValue());
            summary.setChangePercent(entity.getChangePercent());
            summary.setGainianName(entity.getGainianName());
            summary.setGainianNamepy(PinyinUtils.getWordInitials(entity.getGainianName()));

            // 计算各时间段的汇总，使用bean的setter替代map.put
            summary.setDay2now(day2all.get(code) != null ? day2all.get(code).getSealOrderAmount() : new BigDecimal(0));
            summary.setDay3now(day3all.get(code) != null ? day3all.get(code).getSealOrderAmount() : new BigDecimal(0));
            // summary.setDay4now(day4all.get(code) != null ? day4all.get(code).getSealOrderAmount() : 0);
            summary.setDay5now(day5all.get(code) != null ? day5all.get(code).getSealOrderAmount() : new BigDecimal(0));
            summary.setDay6now(day6all.get(code) != null ? day6all.get(code).getSealOrderAmount() : new BigDecimal(0));
            summary.setDay7now(day7all.get(code) != null ? day7all.get(code).getSealOrderAmount() : new BigDecimal(0));

            summary.setDay20(map20.get(code));
            summary.setDay10(map10.get(code));
            summary.setDay7(map7.get(code));
            summary.setDay6(map6.get(code));
            summary.setDay5(map5.get(code));
            summary.setDay4(map4.get(code));
            summary.setDay3(map3.get(code));
            summary.setDay2(map2.get(code));
            summary.setDay1(map1.get(code));

            Integer suns = sunstocks.get(entity.getGainianName());
            if ((suns == null || suns == 0) && (allStock != null && allStock.size() > 0)) {
                suns = 0;
                continue;
            }
            summary.setSunstocks(suns);

            Integer sunsup = sunstocksUP.get(entity.getGainianName());
            if (sunsup == null || sunsup == 0) {
                sunsup = 0;
            }
            summary.setSunstocksup(sunsup);

            // 计算上涨比例
            Double sunstocksupratio = (suns == 0 || suns==null)? 0.00 : (double) sunsup / suns;
            summary.setSunstocksupratio(sunstocksupratio * 100);

            Integer sunslimit = sunstockslimit.get(entity.getGainianName());
            if (sunslimit == null || sunslimit == 0) {
                sunslimit = 0;
            }
            summary.setSunstockslimit(sunslimit);

            // 计算涨停比例
            Double sunstockslimitratio = suns == 0 ? 0.00 : (double) sunslimit / suns;
            summary.setSunstockslimitratio(sunstockslimitratio * 100);

            result.add(summary);
        }

        Collections.sort(result, (o1, o2) -> {
//            BigDecimal d1 = (BigDecimal) o1.get("day1");
//            BigDecimal d2 = (BigDecimal) o2.get("day1");
            Long d2 = (Long) o1.getRankPosition();//.get("rankPosition");
            Long d1 = (Long) o2.getRankPosition();//.get("rankPosition");
            if (d1 == null && d2 == null) return 0;
            if (d1 == null) return 1;  // null值排最后
            if (d2 == null) return -1;
            return d2.compareTo(d1);
        });
        log.info("allStock==22222==" + result.size());
        gaiNianDTO.setResult(result);
        gaiNianDTO.setTodayAll(todayAll);
        gaiNianDTO.setTodayAllMain(todayAllMain);

//        log.info("allStock==gaiNianDTO==" + gaiNianDTO);
//        checkGaiNian(result);
        gaiNianDTO.setFlowGainian(iwencaiConfig.getFocusGaiNian());
        return gaiNianDTO;
    }

    /**
     * 指定概念数据
     * @param now
     * @param code
     * @return
     */
    public GaiNianDTO getSealOrderAmountSummaryCode(LocalDateTime now, String code) {
        GaiNianDTO gaiNianDTO = new GaiNianDTO();
        if (now == null) {
            now = LocalDateTime.now();
        }
        List<SummaryBean> result = new ArrayList<>();

        log.info("getSealOrderAmountSummaryCode=====1");
        LocalDate today = now.toLocalDate();//today.minusDays(1);
//        List<Stock> allStock = stockRepository.findByTradeDateBetweenOrderByCodeAscTradeDateAsc(today, today);
        Map<String, Integer> sunstocks = new HashMap<>();
        Map<String, Integer> sunstocksUP = new HashMap<>();//上涨的家数
        Integer stocksUP = 0;//上涨的家数
        Integer stocksDown = 0;//下跌的家数
        Integer stocksLimit = 0;//涨停的家数
        Integer stockspin = 0;//平的家数

        log.info("getSealOrderAmountSummary=====2");
//        Map<String, Integer> sunstockslimit = new HashMap<>();//涨停数量
//        List<StockLimitUp> stocks = stockLimitUpService.getTodayLimitUpStocksBy(LocalDateTime.of(today, LocalTime.MIDNIGHT), LocalDateTime.of(today, LocalTime.MAX));

        gaiNianDTO.setStocksLimit(stocksLimit);
        gaiNianDTO.setStocksUP(stocksUP);
        gaiNianDTO.setStocksDown(stocksDown);
        gaiNianDTO.setStocksPin(stockspin);
//        gaiNianDTO.setAllstocks(allStock.size());
        gaiNianDTO.setFlowGainian(iwencaiConfig.getFocusGaiNian());

        List<GaiNianInfo> allEntities = repository.findByCreateTimeBetweenAndCode(LocalDateTime.of(today.minusDays(60), LocalTime.MIDNIGHT), LocalDateTime.of(today, LocalTime.MAX), code);//repository.findByCreateTime(LocalDateTime.of(today, LocalTime.MIDNIGHT));
        log.info(allEntities + "==" + allEntities.size());
        if (allEntities == null || allEntities.size() <= 0) {
            return gaiNianDTO;
        }
        Map<String, Integer> sunstockslimit = new HashMap<>();//涨停数量
        List<StockLimitUp> stocks = stockLimitUpService.getTodayLimitUpStocksBy(LocalDateTime.of(today.minusDays(60), LocalTime.MIDNIGHT), LocalDateTime.of(today, LocalTime.MAX));
        for (StockLimitUp stock : stocks) {
            String concept = stock.getGainians();

            DateTimeFormatter parser = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            String times = timeFormat(stock.getCreateTime(), parser);
            String limitUpReason = stock.getLimitUpReason();
            if (concept != null && !concept.isEmpty()) {// 按分号分割概念字符串
                // 优化后的代码
                String[] parts = {};
                String[] partsr = {};

                // 处理第一个字符串的分割，避免空指针和空字符串
                if (concept != null && !concept.isEmpty()) {
                    parts = concept.split(";");
                }

                // 处理第二个字符串的分割，注意split需要转义，同时避免空指针和空字符串
                if (limitUpReason != null && !limitUpReason.isEmpty()) {
                    partsr = limitUpReason.split("\\+"); // 这里需要用\\+转义，否则会报错
                }

                // 合并两个数组并去重
                Set<String> resultSet = new HashSet<>();
                // 添加第一个数组的元素
                resultSet.addAll(Arrays.asList(parts));
                // 添加第二个数组的元素（Set会自动去重）
                resultSet.addAll(Arrays.asList(partsr));

                // 转换为数组（如果需要）
                String[] finalResult = resultSet.toArray(new String[0]);
                for (String part : finalResult) {
                    if (!part.trim().isEmpty()) {
                        sunstockslimit.put(part + times, sunstockslimit.get(part + times) == null ? 1 : sunstockslimit.get(part + times) + 1);
                    }
                }
            }
            stocksLimit = stocks.size();
        }

        int[] arr = new int[]{5, 10, 20, 30, 40, 60};

        int index = 30;
        if (allEntities != null && allEntities.size() < index) {
            index = allEntities.size();
        }

        Collections.sort(allEntities, (o1, o2) -> {
            LocalDateTime time1 = o1.getCreateTime();
            LocalDateTime time2 = o2.getCreateTime();
            // 处理null值情况：null值排在最后
            if (time1 == null && time2 == null) return 0;
            if (time1 == null) return 1;  // o1为null，排在后面
            if (time2 == null) return -1; // o2为null，o1排在前面

            // 降序排列：用time2.compareTo(time1)替代time1.compareTo(time2)
            return time2.compareTo(time1);
        });

        if (allEntities != null && allEntities.size() > index) {
//            log.info(allStock);

            // 处理指定天数的统计数据
            GaiNianInfo latestStock = allEntities.get(0);
            gaiNianDTO.setCreatedAt(latestStock.getCreateTime());
            System.out.println(latestStock);
            for (int days : arr) {
                if (days > allEntities.size()) {
                    continue;
                }
//                    LocalDateTime latestTime = latestStock.getCreateTime();
//                    if (latestTime == null) {
//                        latestTime = LocalDateTime.now();
//                    }

//                Map<String, Object> summary = new LinkedHashMap<>();
//                SummaryBean summary = new SummaryBean();
////                    summary.put("day1", latestStock.getSealOrderAmount());
//                summary.setGainianCode(code);//.put("gainianCode", code);
//                summary.put("rankPosition", latestStock.getRankPosition());
//                summary.put("oldRankPosition", latestStock.getOldRankPosition());
//                summary.put("marketValue", latestStock.getMarketValue());
//                summary.put("changePercent", latestStock.getChangePercent());
//                summary.put("gainianName", latestStock.getGainianName());
//                summary.put("gainianNamepy", PinyinUtils.getWordInitials(latestStock.getGainianName()));
//                summary.put("CreateTime", "最近" + days + "天");
//
//                // 计算各时间段的汇总
//                summary.put("day1", calculateSumMainCapitalInRange(allEntities, LocalDateTime.of(LocalDateTime.now().toLocalDate(), LocalTime.MAX), 0, days - 1));
////                    summary.put("day3now", calculateSumMainCapitalInRange(allEntities, latestTime, 0, days));
////                    summary.put("day4now", calculateSumMainCapitalInRange(allEntities, latestTime, 0, days));
////                    summary.put("day5now", calculateSumMainCapitalInRange(allEntities, latestTime, 0, days));
////                    summary.put("day6now", calculateSumMainCapitalInRange(allEntities, latestTime, 0, days));
////                    summary.put("day7now", calculateSumMainCapitalInRange(allEntities, latestTime, 0, days));
//
//                // 处理概念统计数据
//                String gainianName = latestStock.getGainianName();
//                Integer suns = sunstocks.getOrDefault(gainianName, 0);
//                if (suns <= 0) {
////                        continue;
//                    suns = 0;
//                }
//
//                summary.put("sunstocks", suns);
//
//                Integer sunsup = sunstocksUP.getOrDefault(gainianName, 0);
//                summary.put("sunstocksup", sunsup);
//
//                double sunstocksupratio = suns > 0 ? (double) sunsup / suns * 100 : 0;
//                summary.put("sunstocksupratio", sunstocksupratio);
//
//                Integer sunslimit = sunstockslimit.getOrDefault(gainianName, 0);
//                summary.put("sunstockslimit", sunslimit);
//
//                double sunstockslimitratio = suns > 0 ? (double) sunslimit / suns * 100 : 0;
//                summary.put("sunstockslimitratio", sunstockslimitratio);

                SummaryBean summary = new SummaryBean();
// summary.put("day1", latestStock.getSealOrderAmount());
                summary.setGainianCode(code); // 替换.put("gainianCode", code)
                summary.setRankPosition(latestStock.getRankPosition());
                summary.setOldRankPosition(latestStock.getOldRankPosition());
                summary.setMarketValue(latestStock.getMarketValue());
                summary.setChangePercent(latestStock.getChangePercent());
                summary.setGainianName(latestStock.getGainianName());
                summary.setGainianNamepy(PinyinUtils.getWordInitials(latestStock.getGainianName()));
                summary.setCreateTime("最近" + days + "天"); // 对应原key: CreateTime

                // 计算各时间段的汇总
                summary.setDay1(calculateSumMainCapitalInRange(allEntities, LocalDateTime.of(LocalDateTime.now().toLocalDate(), LocalTime.MAX), 0, days - 1));
                // summary.setDay3now(calculateSumMainCapitalInRange(allEntities, latestTime, 0, days));
                // summary.setDay4now(calculateSumMainCapitalInRange(allEntities, latestTime, 0, days));
                // summary.setDay5now(calculateSumMainCapitalInRange(allEntities, latestTime, 0, days));
                // summary.setDay6now(calculateSumMainCapitalInRange(allEntities, latestTime, 0, days));
                // summary.setDay7now(calculateSumMainCapitalInRange(allEntities, latestTime, 0, days));

                // 处理概念统计数据
                String gainianName = latestStock.getGainianName();
                Integer suns = sunstocks.getOrDefault(gainianName, 0);
                if (suns <= 0) {
                    // continue;
                    suns = 0;
                }

                summary.setSunstocks(suns);

                Integer sunsup = sunstocksUP.getOrDefault(gainianName, 0);
                summary.setSunstocksup(sunsup);

                double sunstocksupratio = suns > 0 ? (double) sunsup / suns * 100 : 0;
                summary.setSunstocksupratio(sunstocksupratio);

                Integer sunslimit = sunstockslimit.getOrDefault(gainianName, 0);
                summary.setSunstockslimit(sunslimit);

                double sunstockslimitratio = suns > 0 ? (double) sunslimit / suns * 100 : 0;
                summary.setSunstockslimitratio(sunstockslimitratio);

                result.add(summary);
            }

            for (int i = 0; i < index; i++) {
                // 获取最新记录的创建时间作为基准
                GaiNianInfo entity = allEntities.get(i);
                LocalDateTime latestTime = entity.getCreateTime();
                latestTime = LocalDateTime.of(latestTime.toLocalDate(), LocalTime.MAX);
//                Map<String, Object> summary = new LinkedHashMap<>();
                // String code = entity.getGainianCode();

//                    gaiNianDTO.setCreatedAt(entity.getCreateTime());
//                summary.put("gainianCode", code);
//                summary.put("CreateTime", entity.getCreateTime());
//
//                summary.put("rankPosition", entity.getRankPosition());
//                summary.put("oldRankPosition", entity.getOldRankPosition());
//
//                summary.put("marketValue", entity.getMarketValue());
//                summary.put("changePercent", entity.getChangePercent());
//                summary.put("gainianName", entity.getGainianName());
//                summary.put("gainianNamepy", PinyinUtils.getWordInitials(entity.getGainianName()));
//
//                // 计算各时间段的汇总
//                summary.put("day1", entity.getSealOrderAmount());
//                summary.put("day2now", calculateSumMainCapitalInRange(allEntities, latestTime, i, 1));
//                summary.put("day3now", calculateSumMainCapitalInRange(allEntities, latestTime, i, 2));
//                summary.put("day4now", calculateSumMainCapitalInRange(allEntities, latestTime, i, 3));
//                summary.put("day5now", calculateSumMainCapitalInRange(allEntities, latestTime, i, 4));
//                summary.put("day6now", calculateSumMainCapitalInRange(allEntities, latestTime, i, 5));
//                summary.put("day7now", calculateSumMainCapitalInRange(allEntities, latestTime, i, 6));
//
////                    summary.put("day7", map7.get(code));
////                    summary.put("day6", map6.get(code));
////                    summary.put("day5", map5.get(code));
////                    summary.put("day4", map4.get(code));
////                    summary.put("day3", map3.get(code));
////                    summary.put("day2", map2.get(code));
////                    summary.put("day1", map1.get(code));
//                Integer suns = sunstocks.get(entity.getGainianName());
//                if (suns == null || suns == 0) {
////                        continue;
//                    suns = 0;
//                }
//                summary.put("sunstocks", suns);
//
//                Integer sunsup = sunstocksUP.get(entity.getGainianName());
//                if (sunsup == null || sunsup == 0) {
//                    sunsup = 0;
//                }
//
//                summary.put("sunstocksup", sunsup);
//
//                Double sunstocksupratio = suns == 0 ? 0.00 : new Double(sunsup.intValue()) / new Double(suns.intValue());
//                summary.put("sunstocksupratio", sunstocksupratio * 100);
//
//                DateTimeFormatter parser = DateTimeFormatter.ofPattern("yyyy-MM-dd");
//                String times = timeFormat(entity.getCreateTime(), parser);
//                Integer sunslimit = sunstockslimit.get(entity.getGainianName()+times);
//                if (sunslimit == null || sunslimit == 0) {
//                    sunslimit = 0;
//                }
//                summary.put("sunstockslimit", sunslimit);
//                summary.put("sunstockslimitratio", (suns == 0 ? 0.00 : new Double(sunslimit.intValue()) / new Double(suns.intValue())) * 100);

                SummaryBean summary = new SummaryBean();
                summary.setGainianCode(code);
                summary.setCreateTime(entity.getCreateTime().toString());

                summary.setRankPosition(entity.getRankPosition());
                summary.setOldRankPosition(entity.getOldRankPosition());

                summary.setMarketValue(entity.getMarketValue());
                summary.setChangePercent(entity.getChangePercent());
                summary.setGainianName(entity.getGainianName());
                summary.setGainianNamepy(PinyinUtils.getWordInitials(entity.getGainianName()));

                // 计算各时间段的汇总
                summary.setDay1(entity.getSealOrderAmount());
                summary.setDay2now(calculateSumMainCapitalInRange(allEntities, latestTime, i, 1));
                summary.setDay3now(calculateSumMainCapitalInRange(allEntities, latestTime, i, 2));
                summary.setDay4now(calculateSumMainCapitalInRange(allEntities, latestTime, i, 3));
                summary.setDay5now(calculateSumMainCapitalInRange(allEntities, latestTime, i, 4));
                summary.setDay6now(calculateSumMainCapitalInRange(allEntities, latestTime, i, 5));
                summary.setDay7now(calculateSumMainCapitalInRange(allEntities, latestTime, i, 6));

//                    summary.setDay7(map7.get(code));
//                    summary.setDay6(map6.get(code));
//                    summary.setDay5(map5.get(code));
//                    summary.setDay4(map4.get(code));
//                    summary.setDay3(map3.get(code));
//                    summary.setDay2(map2.get(code));
//                    summary.setDay1(map1.get(code));

                Integer suns = sunstocks.get(entity.getGainianName());
                if (suns == null || suns == 0) {
//                        continue;
                    suns = 0;
                }
                summary.setSunstocks(suns);

                Integer sunsup = sunstocksUP.get(entity.getGainianName());
                if (sunsup == null || sunsup == 0) {
                    sunsup = 0;
                }
                summary.setSunstocksup(sunsup);

                Double sunstocksupratio = suns == 0 ? 0.00 : (double) sunsup / suns;
                summary.setSunstocksupratio(sunstocksupratio * 100);

                DateTimeFormatter parser = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                String times = timeFormat(entity.getCreateTime(), parser);
                Integer sunslimit = sunstockslimit.get(entity.getGainianName() + times);
                if (sunslimit == null || sunslimit == 0) {
                    sunslimit = 0;
                }
                summary.setSunstockslimit(sunslimit);

                double sunstockslimitratio = suns == 0 ? 0.00 : (double) sunslimit / suns;
                summary.setSunstockslimitratio(sunstockslimitratio * 100);

                result.add(summary);
            }
        }

        log.info("allStock==22222==" + result.size());
        gaiNianDTO.setResult(result);
        return gaiNianDTO;
    }

    /**
     * 计算指定天数范围内的主力资金流向总和
     * @param gaiNianInfos 股票列表（已按时间降序排序）
     * @param baseTime     基准时间（最新记录的创建时间）
     * @param startDaysAgo 起始天数（几天前）
     * @param endDaysAgo   结束天数（几天前）
     * @return 总和（null视为0）
     */
    private BigDecimal calculateSumMainCapitalInRange(List<GaiNianInfo> gaiNianInfos, LocalDateTime baseTime, int startDaysAgo, int endDaysAgo) {
//        LocalDateTime startTime = baseTime.minusDays(endDaysAgo);
//        LocalDateTime endTime = baseTime.minusDays(startDaysAgo);
        LocalDateTime startTime = DateUtils.minusDaysExcludeWeekendAndYesterday(baseTime, endDaysAgo);
//        log.info("startTime==" + startTime);
//        log.info("baseTime==" + baseTime);
        return gaiNianInfos.stream()
                .filter(stock -> {
                    LocalDateTime createdAt = stock.getCreateTime();
                    // 过滤出在指定时间范围内的记录
                    return createdAt != null &&
                            createdAt.isAfter(startTime) &&
                            createdAt.isBefore(baseTime);
                })
                .map(stock -> stock.getSealOrderAmount() != null ? stock.getSealOrderAmount() : BigDecimal.ZERO)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    private Map<String, BigDecimal> calculateSummaryForDays(LocalDateTime now, int days) {
        LocalDateTime startTime = DateUtils.minusDaysExcludeWeekendAndYesterday(now, days);
//        log.info(days+"===="+startTime.toString()+"==================="+now.toString());
        List<Map<String, Object>> records = repository.sumSealOrderAmountByTimeRange(startTime, now);
//        log.info(records);
        if (records == null) {
            return new HashMap<>();
        }
//        return records.stream()
//                .filter(e -> e.get("gainianCode") != null && e.get("totalAmount") != null)
//                .collect(Collectors.toMap(
//                        e -> e.get("gainianCode").toString(),
//                        v -> (BigDecimal) v.get("totalAmount")
//                ));


        return records.stream()
                // 过滤 gainianCode 或 totalAmount 为 null 的记录（避免空指针）
                .filter(e -> e.get("gainianCode") != null && e.get("totalAmount") != null)
                .collect(Collectors.toMap(
                        // key：gainianCode 转字符串
                        e -> e.get("gainianCode").toString(),
                        // value：totalAmount 转 BigDecimal（注意类型转换安全）
                        v -> {
                            Object amountObj = v.get("totalAmount");
                            // 兼容可能的数值类型（如 Long、Double 转 BigDecimal）
                            if (amountObj instanceof BigDecimal) {
                                return (BigDecimal) amountObj;
                            } else if (amountObj instanceof Number) {
                                return new BigDecimal(amountObj.toString());
                            } else {
                                return BigDecimal.ZERO;
                            }
                        },
                        // 关键：重复 key 时，金额累加（解决 Duplicate key 问题）
                        BigDecimal::add,
                        // 可选：指定 Map 实现类（如 HashMap）
                        HashMap::new
                ));

//        return records.stream().collect(Collectors.toMap(e -> e.get("gainianCode").toString(), v -> (BigDecimal) v.get("totalAmount")));
    }



    public String gainiancheckAndDateRangeBoll() {

        List<GaiNianInfo> allEntities = repository.findByCreateTimeBetween(LocalDateTime.of(LocalDate.now(), LocalTime.MIDNIGHT), LocalDateTime.of(LocalDate.now(), LocalTime.MAX));

//        List<GaiNianInfo> allEntities = repository.findByCreateTimeBetweenAndCode(LocalDateTime.of(LocalDate.now(), LocalTime.MIDNIGHT), LocalDateTime.of(LocalDate.now(), LocalTime.MAX),"培育钻石");

        System.out.println("allEntities==="+allEntities.size());
        String res = "";
//        Map<String, String> codestockMap = new HashMap<>();
//
//        String flowstock = iwencaiConfig.getFocus();
//        String[] flowstocks = new String[0];
//        if (flowstock != null && !flowstock.isEmpty()) {// 分割并过滤空字符串
//            flowstocks = Arrays.stream(flowstock.split(","))
//                    .filter(s -> !s.isEmpty())
//                    .toArray(String[]::new);
//
//            for (int i = 0; i < flowstocks.length; i++) {
//                codestockMap.put(flowstocks[i], flowstocks[i]);
//            }
//        }
//
//        Set<String> keySet = codestockMap.keySet();
//        for (String code : keySet) {
        for (int i = 0; i < allEntities.size(); i++) {
            GaiNianInfo gaiNianInfo = allEntities.get(i);
            String gname =gaiNianInfo.getGainianName();
            String gcode =gaiNianInfo.getGainianCode();
            List<GaiNianInfo> gaiNianInfos = repository.findByCreateTimeBetweenAndCode(LocalDateTime.of(LocalDate.now().minusDays(60), LocalTime.MIN), LocalDateTime.of(LocalDate.now(), LocalTime.MAX), gname);
//            System.out.println(gname+"===gaiNianInfos=="+gaiNianInfos);
//            List<Stock> allStock = stockRepository.findByCodeAndCreatedAtBetweenOrderByTradeDateAsc(code, LocalDateTime.of(startDate, LocalTime.MIN), LocalDateTime.of(LocalDate.now(), LocalTime.MAX));
            //            System.out.println("Stock allStock=="+allStock.size()+"="+allStock);
            if (gaiNianInfos.isEmpty()) {
                continue;
            }
            // 按创建时间降序排序，确保最新数据在前面
            gaiNianInfos.sort(Comparator.comparing(GaiNianInfo::getCreateTime).reversed());

            int index = 20;
            if (gaiNianInfos != null && gaiNianInfos.size() < index) {
                index = gaiNianInfos.size();
            }

            boolean flag = true;
            if (gaiNianInfos != null && gaiNianInfos.size() >= index && gaiNianInfos.size()>2 ) {
                GaiNianInfo stock0 = gaiNianInfos.get(0); // 今天的数据
                GaiNianInfo stock1 = gaiNianInfos.get(1); // 今天的数据
                GaiNianInfo stock2 = gaiNianInfos.get(2); // 今天的数据
                //                Stock stock3 = allStock.get(3); // 今天的数据
                //                Stock stock4 = allStock.get(4); // 今天的数据

                List<Stock> stockList = new ArrayList<>();
                stockList.add(addStockFromBollField(stock0));
                stockList.add(addStockFromBollField(stock1));
                stockList.add(addStockFromBollField(stock2));

                //                stockList.add(stock3);
                //                stockList.add(stock4);

//                double profitPercent = 0.0;
//                double highCPercent = 0.0;//最高价与现价征服

                //                Set<String> stockset = DataUtil.processSecondString(stock0.getConcept());

                // 检查交集
                //                boolean hasIntersection = DataUtil.checkIntersection(Reviewset, stockset);

//                if (stock0.getMainCost() != null && stock0.getMainCost() != 0) {
//                    profitPercent = ((stock0.getClose() - stock0.getMainCost()) / stock0.getMainCost());
//                }

//                highCPercent=((stock0.getHigh() - stock0.getClose()) / stock0.getClose());
//                boolean mainstockFlag = allMatchConditionStock(stock0);
//                boolean mainFlag = (stock0.getMainCapitalFlow()!=null && stock0.getMainCapitalFlow().compareTo(new BigDecimal(10*10000))>0);
//                boolean highClostFlag = (stock0.getClose()>=stock0.getOpen());
                //                boolean main5DFlag = (calculateTotalMainCapitalFlow(stockList,0).compareTo(new BigDecimal(1000*10000))>0); //5天主力流入
                //                boolean main10DFlag = (calculateTotalMainCapitalFlow(stockList,0).compareTo(new BigDecimal(1000*10000))>0); //5天主力流入
//                boolean mainCost5DFlag = allMatchCondition(stockList); //5天主力成本都是再增加
                //                boolean capitalFlag = (stock0.getCapitalFlow()!=null && stock0.getCapitalFlow().compareTo(new BigDecimal(1000*10000))>0);
                if (stock0 != null
//                        && mainstockFlag //主力流入或散户流出多
//                        && mainFlag //当天主力进入十万
                        //                        && hasIntersection //有关联概念
//                        && mainCost5DFlag //5天主力成本都是再增加
                        //                        && stock0.getTurnoverRate() <= 30 && stock0.getRsi6() > 30 && stock0.getRsi6() >= stock0.getRsi12() && stock0.getRsi12() >= stock0.getRsi24()
//                            && profitPercent <= 0.16 && profitPercent >= 0.01 //获利 1%~20%之间
//                        && stock0.getTurnoverRate() > 2 && stock0.getTurnoverRate() < 20 //换手率
                        && stock0.getChangePercent()!=null && stock0.getChangePercent()<=20.5 && stock0.getChangePercent()>=0.01 //涨幅在0.01~20.5%之间
//                        && highClostFlag //大于开盘价
//                        && Math.abs(highCPercent)<=3 //振幅3%以内
                        && stock0.getRankPosition() <= 300 //热度前300
                        && stock0.getRankPosition()<=stock0.getOldRankPosition() //热度上升
                ) {
                    //60分boll扩张
                    List<Stock> threeDaysData = new ArrayList<>();
                    List<Gainian60Boll> s60bolls = gainian60BollRepository.findRecentDataByCode(gcode,DateUtils.minusDaysExcludeWeekendAndYesterday(LocalDateTime.now(),2).toLocalDate());
                    if (s60bolls!=null){
                        List<Stock>  s60bollsToStock = s60bollsToStock(s60bolls);
//                        System.out.println("s60bollsToStock=="+s60bollsToStock);
                        if (s60bollsToStock!=null && s60bollsToStock.size()>=2){
                            threeDaysData.add(s60bollsToStock.get(0));
                            threeDaysData.add(s60bollsToStock.get(1));
                            threeDaysData.add(s60bollsToStock.get(2));
                            BollingerBandCalculator calculator = new BollingerBandCalculator();
                            BollingerBandCalculator.BollingerAnalysisResult todayResult = calculator.judgeTodayLimitStatus(threeDaysData, 0.001);
//                            System.out.println("todayResult==="+todayResult);
                            if (todayResult.getBandStatus().getKey().equals("EXPANDING")) {
                                flag = true;
                            } else {
                                flag = false;
                            }
                        }else{
                            flag = false;
                        }
                    }else{
                        flag = false;
                    }

//                    //日开口
                    if (flag) {
                        BollingerBandCalculator calculator = new BollingerBandCalculator();
                        BollingerBandCalculator.BollingerAnalysisResult t3dResult = calculator.judgeTodayStatus(stockList, 0.001);
//                        System.out.println("t3dResult==="+t3dResult);
                        if (t3dResult.getBandStatus().getKey().equals("EXPANDING")) {
                            flag = true;
                        } else {
                            flag = false;
                        }
                    }
//                        log.info("checkAndDateRangeBollFlow threeDaysData=="+threeDaysData+"==="+codestock.getCode());
                } else {
                    flag = false;
                }

                if (flag) {
                    List<Stock>  stocks = stockRepository.findByTradeDateBetweenAndCodeLikeOrderByConceptAscTradeDateDesc(LocalDate.now(), LocalDate.now(),gname);
//                    System.out.println("stocks==="+stocks);
                    if (stocks!=null && stocks.size()>0) {
                        res += gname + ",";
                    }
                }
            }
//            }
        }

        SysInfo sysInfo = new SysInfo();
        sysInfo.setSysKey("focusGainian");
        sysInfo.setSysValue(res);
        sysInfo.setTypes(0);
        sysInfo.setCreateTime(LocalDateTime.now());
        stockService.upsertSysInfo(sysInfo);//

        log.info("gainiancheckAndDateRangeBoll===res==" + res);
        return res;
    }


    public boolean getGaiNianStockNotNull(String gname){
        List<Stock>  stocks = stockRepository.findByTradeDateBetweenAndCodeLikeOrderByConceptAscTradeDateDesc(LocalDate.now().minusDays(20), LocalDate.now(),gname);
//                    System.out.println("stocks==="+stocks);
        if (stocks!=null && stocks.size()>0) {
            return true;
        }else{
            return  false;
        }
    }
    /**
     * 60分钟获取最近的boll值
     * @param s60bolls
     * @return
     */
    public List<Stock> s60bollsToStock(List<Gainian60Boll> s60bolls){
        if (s60bolls == null || s60bolls.isEmpty()) {
            log.warn("s60bolls list is null or empty");
            return new ArrayList<>();
        }

        // 转换并按时间降序排列
        return s60bolls.stream()
                .filter(Objects::nonNull)
                .flatMap(this::convertSingleStock60Boll)
                .sorted(Comparator.comparing(Stock::getCreatedAt).reversed()) // 按时间降序
                .collect(Collectors.toList());
    }

    /**
     * 转换单个Stock60Boll为多个Stock对象（每个时间点一个）
     */
    private java.util.stream.Stream<Stock> convertSingleStock60Boll(Gainian60Boll stock60Boll) {
        List<Stock> stocks = new ArrayList<>();

        // 处理各个时间点的boll数据
        addStockFromBollField(stock60Boll, stock60Boll.getBoll9(), LocalTime.of(9, 30), stocks);
        addStockFromBollField(stock60Boll, stock60Boll.getBoll10(), LocalTime.of(10, 30), stocks);
        addStockFromBollField(stock60Boll, stock60Boll.getBoll11(), LocalTime.of(11, 30), stocks);
        addStockFromBollField(stock60Boll, stock60Boll.getBoll13(), LocalTime.of(13, 0), stocks);
        addStockFromBollField(stock60Boll, stock60Boll.getBoll14(), LocalTime.of(14, 0), stocks);
        addStockFromBollField(stock60Boll, stock60Boll.getBoll15(), LocalTime.of(15, 0), stocks);

        return stocks.stream();
    }

    /**
     * 从boll字段创建Stock对象
     */
    private void addStockFromBollField(Gainian60Boll stock60Boll, String bollValue,
                                       LocalTime time, List<Stock> stocks) {

        if (bollValue == null || bollValue.trim().isEmpty()) {
            return;
        }

        try {
            String[] values = bollValue.split("#");

            if (values.length < 4) {
                log.error("Invalid boll format: {} for stock {}", bollValue, stock60Boll.getCode());
                return;
            }

            LocalDate tradeDate = stock60Boll.getTradeDate();
            LocalDateTime createdAt = LocalDateTime.of(tradeDate, time);
            Stock stock = new Stock();
            stock.setCode(stock60Boll.getCode());
            stock.setName(stock60Boll.getName());
            stock.setCreatedAt(createdAt);
            stock.setBollMid(parseDouble(values[0]));
            stock.setBollLower(parseDouble(values[1]));
            stock.setBollUpper(parseDouble(values[2]));
            stock.setClose(parseDouble(values[3]));
            stocks.add(stock);

        } catch (Exception e) {
            log.error("Error converting boll value: {}", bollValue, e);
        }
    }

    /**
     * 安全解析double值
     */
    private Double parseDouble(String value) {
        if (value == null || value.trim().isEmpty()) {
            return null;
        }

        try {
            return Double.parseDouble(value);
        } catch (NumberFormatException e) {
            log.error("Invalid number format: {}", value, e);
            return null;
        }
    }


    /**
     * 从boll字段创建Stock对象
     */
    private Stock addStockFromBollField(GaiNianInfo stock60Boll) {

        if (stock60Boll == null) {
            return null;
        }

        try {
//            LocalDate tradeDate = stock60Boll.getTradeDate();
//            LocalDateTime createdAt = LocalDateTime.of(tradeDate, time);
            Stock stock = new Stock();
            stock.setCode(stock60Boll.getGainianCode());
            stock.setName(stock60Boll.getGainianName());
            stock.setCreatedAt(stock60Boll.getCreateTime());
            stock.setBollMid(stock60Boll.getBollMid());
            stock.setBollLower(stock60Boll.getBollLower());
            stock.setBollUpper(stock60Boll.getBollUpper());
            stock.setClose(stock60Boll.getCurrentPrice()==null?0.0:stock60Boll.getCurrentPrice().doubleValue());
//            stocks.add(stock);
            return stock;
        } catch (Exception e) {
            log.error("Error converting boll value: {}", stock60Boll, e);
            return null;
        }
    }

}